package models;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

import com.hp.hpl.jena.rdf.model.Resource;

import controllers.utils.EntityUtil;


public class EntityContainer implements Comparable<EntityContainer>
{
    private Target             source;
    private Resource           subject;
    private Set<PropertyModel> properties;
    private double             confidence;
    private String             validationLink;
    private String[]           readableNames;


    public EntityContainer(Resource subject, Target source)
    {
        this.subject = subject;
        this.source = source;
        // If ordering doesn't matter, LinkedHashSet can be replaced by a regular HashSet
        this.properties = new LinkedHashSet<PropertyModel>();
        this.confidence = -1.0f;
    }


    public String getLocalName()
    {
        return EntityUtil.getLocalName(this.subject.toString(), true);
    }


    public Set<String> getKeywords()
    {
        return EntityUtil.getShortDescription(this.properties);
    }


    public String getURI()
    {
        return subject.toString();
    }


    public Set<PropertyModel> getProperties()
    {
        return properties;
    }


    public void setProperties(Set<PropertyModel> properties)
    {
        this.properties = properties;
    }


    public void addProperty(PropertyModel property)
    {
        this.properties.add(property);
    }


    public boolean contains(PropertyModel pm)
    {
        return this.properties.contains(pm);
    }


    public double getConfidence()
    {
        return confidence;
    }


    public void setConfidence(double confidence)
    {
        this.confidence = confidence;
    }


    public Target getSource()
    {
        return source;
    }


    public String[] getReadableNames()
    {
        return readableNames;
    }


    public void setReadableNames(String... readableName)
    {
        this.readableNames = readableName;
    }


    public String getHTMLLink()
    {
        String link = "<a data-placement=\"right\"  rel=\"tooltip\" title=\"" + getURI() + "\" target=\"_blank\" href=\"";
        if(source == Target.FREEBASE) {
            link += "https://www.freebase.com";
        }
        link += this.getURI() + "\">" + this.getLocalName() + "</a>";
        return link;
    }


    public String getValidationLink()
    {
        return validationLink;
    }


    public void setValidationLink(String validationLink)
    {
        this.validationLink = validationLink;
    }


    public String getEvaluationID()
    {
        if(this.source != Target.FREEBASE) {
            return getURI();
        } else {
            for(PropertyModel p : this.getProperties()) {
                if(p.getURI().equals("/type/object/mid")) { return new TreeSet<String>(p.getValues().get("XX")).first(); }
            }
            return getURI();
        }
    }


    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append(subject.toString() + "\n");
        for(PropertyModel property : properties) {
            sb.append(">> " + property.toString() + "\n");
        }

        return sb.toString();
    }


    @Override
    public int compareTo(EntityContainer o)
    {
        if(this.getConfidence() <= o.getConfidence()) {
            return -1;
        } else {
            return 1;
        }
    }


    @Override
    public boolean equals(Object o)
    {
        if(o instanceof EntityContainer) {
            EntityContainer ec = (EntityContainer) o;
            if(this.getEvaluationID().toString().equals(ec.getEvaluationID().toString()))
                return true;
        }

        return false;
    }


    @Override
    public int hashCode()
    {
        return this.getEvaluationID().toString().hashCode();
    }
}